<?php

defined('BASEPATH') or die('forbidden');

/**
 * SESSION类
 * @author  Karson
 * @name    session.php
 * @since   2011-03-19 11:08:32
 */
class Session {

    var $session_to_db = SESSION_TO_DB;
    var $session_dir = SESSION_DIR;
    var $session_expire = SESSION_EXPIRE;
    var $session_db_name = SESSION_DB_NAME;
    var $db = null;

    function __construct() {
        ini_set('session.cookie_domain', COOKIE_DOMAIN);
        if ($this->session_to_db) {
            $framework = &get_instance('controller');
            $this->db = &$framework->db;
            $this->db->debug = true;
            ini_set('session.save_handler', 'user');
            session_set_save_handler(
                    array(&$this, 'open'), array(&$this, 'close'), array(&$this, 'read'), array(&$this, 'write'), array(&$this, 'destroy'), array(&$this, 'clean')
            );
        } else {
            if (!is_dir($this->session_dir))
                mk_dir($this->session_dir);
            if (is_writeable($this->session_dir) && is_readable($this->session_dir))
                session_save_path($this->session_dir);
            ini_set('session.gc_maxlifetime', $this->session_expire);
        }
        session_start();
    }

    /**
     * 开启SESSIOn设置
     * @param string $path SESSION路径
     * @param string $name SESSION名称
     * @return bool
     */
    function open($path, $name) {
        return isset($this->db) ? true : false;
    }

    /**
     * 清空所有SESSION
     * @return bool
     */
    function close() {
        return $this->clean(0) ? true : false;
    }

    /**
     * 读指定用户的SESSION
     * @param string $sid 用户的唯一SID
     * @return string
     */
    function read($sid) {
        $row = $this->db->one("SELECT * FROM {pre}session WHERE sid = '{$sid}' AND expire>" . time());
        return $row ? $row["data"] : '';
    }

    /**
     * 写SESSION
     * @param string $sid 用户的唯一SID
     * @param string $data SESSION的数据
     * @return bool
     */
    function write($sid, $data) {
        if (isset($_GET['v'])) {
            return true;
        }
        $sid = mysql_real_escape_string($sid);
        $data = mysql_real_escape_string($data);
        $agent = mysql_real_escape_string(isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $_SERVER['REQUEST_URI']);
        $ip = mysql_real_escape_string(get_ip());
        $time = time();
        $expire = ($time + $this->session_expire);
        return!$this->db->query("REPLACE INTO {pre}session VALUES ('{$sid}', '{$ip}', '{$agent}','{$time}', '{$expire}','{$data}')") ? false : true;
    }

    /**
     * 清理指定的SESSION
     * @param string $sid 清理指定SID
     * @return bool
     */
    function destroy($sid) {
        $row = $this->db->query("DELETE FROM {pre}session WHERE sid = '$sid'");
        return (!$row) ? false : true;
    }

    /**
     * 清理过期的SESSION
     * @param int $lifetime 过期的时间
     * @return bool
     */
    function clean() {
        $time = time();
        $row = $this->db->query("DELETE FROM {pre}session WHERE expire < {$time}");
        return!$row ? false : true;
    }

    /**
     * 获取所有在线的用户数
     * @return mixed 成功返回array,失败返回0
     */
    function users() {
        if ($this->session_to_db) {
            $row = $this->db->one("SELECT COUNT(sid) AS num FROM {pre}session");
            return!$row ? 0 : $row['num'];
        } else {
            $dir = opendir($this->session_dir);
            $i = 0;
            while ($filename = readdir($dir)) {
                if ($filename != '.' && $filename != '..') {
                    $i++;
                }
            }
            return $i;
        }
    }

    /**
     * 读取SESSION
     * @param string $field 排序的字段 默认为last_activity，可选sid,data
     * @param string $way 排序的方法，正序或倒序，默认为DESC，即倒序，可选ASC
     * @return array
     */
    function order($field = 'last_activity', $way = 'DESC') {
        $way = strtoupper($way);
        if ($this->session_to_db) {
            $row = $this->db->query("SELECT * FROM {pre}session ORDER BY {$field} {$way}");
            return!$row ? null : $row;
        } else {
            $dir = opendir($this->session_dir);
            $i = 0;
            while ($filename = readdir($dir)) {
                if ($filename != '.' && $filename != '..') {
                    $file = $this->session_dir . '/' . $filename;
                    $row[] = array('sid' => trim(str_replace('sess_', '', $filename)), 'last_activity' => filemtime($file), 'data' => file_get_contents($file));
                }
            }
            foreach ($row as $key => $value) {
                $orderby[] = $value[$field];
            }
            //对数组根据指定的键值排序
            $way == 'DESC' ? array_multisort($orderby, SORT_DESC, $row) : array_multisort($orderby, SORT_ASC, $row);
            return $row;
        }
    }

    /**
     * 设置SESSION值
     * @param string $name SESSION名称
     * @param string $data SESSION数据
     * @return bool 成功返回true，失败返回false
     */
    function set($name, $data, $expire = null) {
        if ($expire != null && is_numeric($expire)) {
            $this->session_expire = $expire;
        }
        if ($name != '' && $data != '') {
            $_SESSION[$name] = $data;
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取SESSION的值
     * @param string $name SESSION名称
     * @return mixed 成功时返回SESSION值，失败返回false
     */
    function get($name) {
        if (isset($_SESSION[$name])) {
            return $_SESSION[$name];
        } else {
            return false;
        }
    }

    /**
     * 删除SESSION
     * @param string $name SESSION名称，为空时删除所有SESSION
     * @return bool 成功返回true
     */
    function clear($name = '') {
        if ($name == '') {
            session_destroy();
            return true;
        } else {
            $_SESSION[$name] = '';
            unset($_SESSION[$name]);
            return true;
        }
    }

}
